package org.wu.framework.easy.markdown.processor;

import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.easy.markdown.endpoint.*;
import org.wu.framework.easy.markdown.utils.MarkdownUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 抽象 处理器
 */
public abstract class AbstractEasyMarkDownProcessor implements EasyMarkDownProcessor {

    /**
     * 导出 markdown
     *
     * @param markdownBeanList markdown 对象
     * @return byte[]
     */
    @Override
    public byte[] exportMarkDown(List<?> markdownBeanList) {
        Object markdownFirstBean = markdownBeanList.stream().findFirst().get();
        Class<?> markdownFirstBeanClass = markdownFirstBean.getClass();
        // 获取数据结构
        EasyMarkDownPoint easyMarkDownPoint = findEasyMarkDownPoint(markdownFirstBeanClass);
        List<EasyMarkDownFieldPoint> markDownFieldPointList = easyMarkDownPoint.getMarkDownFieldPointList();
        MarkDownTable markDownTable = new MarkDownTable();

        // 头数据
        List<MarkDownTableData> markDownTableHeaderDataList = markDownFieldPointList.stream().map(easyMarkDownFieldPoint -> {
            MarkDownTableData markDownTableData = new MarkDownTableData();
            markDownTableData.setValue(easyMarkDownFieldPoint.getName());
            return markDownTableData;
        }).toList();

        markDownTable.setMarkDownTableHeader(markDownTableHeaderDataList);

        // 开始写数据

        List<MarkDownTableRow> markDownTableRowList = listBean2Row(markdownBeanList, markDownFieldPointList);
        markDownTable.setMarkDownTableRowList(markDownTableRowList);
        return MarkdownUtil.markdownTableToByte(markDownTable);
    }

    /**
     * 将集合 转换成行数据
     *
     * @param markdownBeanList       集合数据
     * @param markDownFieldPointList 数据结构
     * @return 多行数据
     */
    public List<MarkDownTableRow> listBean2Row(List<?> markdownBeanList, List<EasyMarkDownFieldPoint> markDownFieldPointList) {
        List<MarkDownTableRow> markDownTableRowList = new ArrayList<>();

        // 开始写数据
        for (Object markdownBean : markdownBeanList) {

            List<MarkDownTableRow> markDownTableRows = oneBean2Row(markdownBean, markDownFieldPointList);
            markDownTableRowList.addAll(markDownTableRows);
        }
        return markDownTableRowList;
    }

    /**
     * 将 对象转换成 行数据
     *
     * @param markdownBean           一个对象
     * @param markDownFieldPointList 对象中的数据结构
     * @return 行数据
     */
    public List<MarkDownTableRow> oneBean2Row(Object markdownBean, List<EasyMarkDownFieldPoint> markDownFieldPointList) {
        List<MarkDownTableRow> markDownTableRowList = new ArrayList<>();
        MarkDownTableRow markDownTableRow = new MarkDownTableRow();
        for (EasyMarkDownFieldPoint easyMarkDownFieldPoint : markDownFieldPointList) {
            MarkDownTableData markDownTableData = new MarkDownTableData();

            Object value = invokeFieldValue(easyMarkDownFieldPoint, markdownBean);

            if (easyMarkDownFieldPoint.isBeanFiled()) {

                // 判断是否有集合结构
                boolean hasCollection = hasCollection(easyMarkDownFieldPoint);
                List<MarkDownTableRow> innerMarkDownTableRowList = oneBean2Row(value, easyMarkDownFieldPoint.getMarkDownBeanFiledPointList());
                if (hasCollection) {
                    markDownTableRowList.addAll(innerMarkDownTableRowList);
                } else {
                    MarkDownTableRow markDownTableOneRow = innerMarkDownTableRowList.get(0);
                    List<MarkDownTableData> markDownTableDataList = markDownTableOneRow.getMarkDownTableDataList();
                    markDownTableRow.addDataList(markDownTableDataList);
                }


            } else if (easyMarkDownFieldPoint.isMapFiled()) {
                // 判断是否有集合结构
                boolean hasCollection = hasCollection(easyMarkDownFieldPoint);
                List<MarkDownTableRow> innerMarkDownTableRowList = oneBean2Row(value, easyMarkDownFieldPoint.getMarkDownBeanFiledPointList());
                if (hasCollection) {
                    markDownTableRowList.addAll(innerMarkDownTableRowList);
                } else {
                    MarkDownTableRow markDownTableOneRow = innerMarkDownTableRowList.get(0);
                    List<MarkDownTableData> markDownTableDataList = markDownTableOneRow.getMarkDownTableDataList();
                    markDownTableRow.addDataList(markDownTableDataList);
                }

            } else if (easyMarkDownFieldPoint.isCollectionFiled()) {
                // 跳过第一个对象
                // colspan
                int rowspan = sumFieldListLength(easyMarkDownFieldPoint, markdownBean);
                markDownTableData.setRowspan(rowspan);
                markDownTableRow.addData(markDownTableData);
//                markDownTableRowList.addDataList();



                List<?> innerFieldValueList = (List<?>) value;
                Object innerFieldFirstValue = innerFieldValueList.get(0);
                // 填充list第一个数据
                List<MarkDownTableRow> markDownTableFirstRowList = oneBean2Row(innerFieldFirstValue, easyMarkDownFieldPoint.getMarkDownBeanFiledPointList());
                markDownTableRowList.addAll(markDownTableFirstRowList);

                List<MarkDownTableRow> innerMarkDownTableRowList = listBean2Row(innerFieldValueList.subList(1, innerFieldValueList.size()), easyMarkDownFieldPoint.getMarkDownBeanFiledPointList());

                markDownTableRowList.addAll(innerMarkDownTableRowList);

            } else {
                // 获取数据
                markDownTableData.setValue(value.toString());
                // 获取当前对象中所有需要合并行数
                markDownTableRow.addData(markDownTableData);
            }


        }
        markDownTableRowList.add(markDownTableRow);

        return markDownTableRowList;
    }


    /**
     * 递归结构中是否存在 集合
     *
     * @param easyMarkDownFieldPoint 结构
     * @return 布尔类型
     */
    public boolean hasCollection(EasyMarkDownFieldPoint easyMarkDownFieldPoint) {
        if (easyMarkDownFieldPoint.isCollectionFiled()) {
            return true;
        } else if (!ObjectUtils.isEmpty(easyMarkDownFieldPoint.getMarkDownBeanFiledPointList())) {
            return easyMarkDownFieldPoint.getMarkDownBeanFiledPointList().stream().anyMatch(this::hasCollection);
        } else {
            return false;
        }
    }

    /**
     * 获取对象中的某个字段
     *
     * @param easyMarkDownFieldPoint 字段数据结构
     * @param markdownBean           对象
     * @return 返回 bean中字段数据
     */
    abstract Object invokeFieldValue(EasyMarkDownFieldPoint easyMarkDownFieldPoint, Object markdownBean);

    /**
     * 如果返回的字段是一个List或者返回对象中某个字段是List 那么递归获取对象中第一个集合的长度和
     *
     * @param easyMarkDownFieldPoint 字段数据结构
     * @param markdownBean           对象
     * @return 获取对象中第一个集合的长度和
     */
    abstract int sumFieldListLength(EasyMarkDownFieldPoint easyMarkDownFieldPoint, Object markdownBean);


}
